package com.tmt.datatable.ext.controller;

import com.tmt.datatable.TableRequest;
import com.tmt.datatable.TableResponse;
import com.tmt.datatable.editor.EditorModel;
import com.tmt.datatable.helper.QueryConditionParser;
import com.tmt.jpa.jpaservice.ITmtBaseRepo;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;

import java.io.Serializable;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * 基础服务接口
 * Created by Stark on 2017/5/15.
 */
public interface ITmtBaseService<T extends Serializable, ID extends Serializable> {

    /**
     * 获取当前服务内的主 repo
     */
    ITmtBaseRepo<T, ID> getRepo();

    /**
     * 处理EditorModel的Create Update Delete事件。
     *
     * @param editorModel
     * @param lazyProperties 要加载的属性
     */
    void executeTableAction(EditorModel<T> editorModel, String[] lazyProperties) throws ExecutionException;


    /**
     * 通过 tableRequest 查找
     *
     * @param request
     * @param clazz
     * @param parser            自定义查询条件分析器
     * @param searchConditions  前端页面上传的搜索条件，互为“或”的关系。
     * @param filterConditions  前端页面上传的数据过滤条件，条件间为"与"的关系。
     *                          filterConditions、 searchConditions、limitedConditions相互为"and"关系
     * @param limitedConditions 服务器上的数据过滤器设置的限制条件，条件间为"and"的关系。
     * @param lazyProperties    要加载的属性
     * @return
     */
    Future<TableResponse<T>> queryByRequest(TableRequest request, Class<T> clazz,
                                            QueryConditionParser parser,
                                            String[] lazyProperties,
                                            Map<String, String[]> searchConditions,
                                            Map<String, String[]> filterConditions,
                                            Map<String, String[]> limitedConditions) throws ExecutionException, InterruptedException;

    /**
     * 为Select2组件查询可选项。
     *
     * @param clazz             目标类型
     * @param idProp            指定返回的的Select2选择项的value值应该填入对象的哪个属性的值。默认填入对象的ID值。
     * @param propName          目标类型的某个属性名称，如果本字段不为空，则目标类型Clazz将被属性的类型替换。目前支持属性类型有：枚举。
     * @param displayExtendInfo 是否显示扩展信息
     * @param search            在前端设定的可搜索字段范围内，进行字段值匹配，各个字段值匹配条件间是或的关系。
     * @param tag               前端特殊查询的自定义标识。
     * @param pageable
     * @param filterConditions  前端页面上传的数据过滤条件，条件间为"or"的关系。filterConditions条件组与limitedConditions条件组为"and"关系
     * @param limitedConditions 服务器上的数据过滤器设置的限制条件，条件间为"and"的关系。
     * @param originParams      原始的请求参数集合
     * @return
     */
    Future<SelectOptions> findForSelect2(Class<T> clazz,
                                         String idProp,
                                         String propName,
                                         boolean displayExtendInfo,
                                         String search,
                                         String tag,
                                         Pageable pageable,
                                         Map<String, String[]> filterConditions,
                                         Map<String, String[]> limitedConditions,
                                         Map<String, String[]> originParams) throws ExecutionException, InterruptedException;

    Future<SelectOptions> findForSelect2Ex(Specification<T> specification, String idProp, boolean displayExtendInfo,
                                           Map<String, String[]> filterConditions, Map<String, String[]> originParams, Pageable pageable) throws ExecutionException, InterruptedException;


    /**
     * 清除不需要返回到前端的对象属性，避免返回的数据太大。
     *
     * @param clazz
     * @return
     */
    void clearProperties(Class<T> clazz, TableResponse<T> response);

}
